﻿@page "/diagramcomponent/organization-model"

@using Syncfusion.Blazor.Inputs
@using System.Collections.ObjectModel
@using Syncfusion.Blazor.Diagram
@using Syncfusion.Blazor.Diagram.Internal
@inherits SampleBaseComponent;

<SampleDescription>
    <p> This sample illustrates a simple business management structure built from an external data source. A hierarchical tree layout algorithm is used to build organizational charts.</p>
</SampleDescription>
<ActionDescription>
    <p>This example shows how to generate an organizational chart from an external data source. The spacing between the objects can also be customized in the chart. The <code class="language-text">HorizontalSpacing</code> and <code class="language-text">VerticalSpacing</code> properties of <code class="language-text">DiagramLayout</code> can be used to customize the space among objects in a tree. The <code class="language-text">Orientation</code> property of <code class="language-text">DiagramLayout</code> can be used to change the orientation of the chart.</p>
</ActionDescription>
@*Hidden:Lines*@
<style>
    #diagram {
        display: block;
    }

    .image-pattern-style {
        background-color: white;
        background-size: contain;
        background-repeat: no-repeat;
        height: 75px;
        width: calc((100% - 18px) / 3);
        cursor: pointer;
        border: 1px solid #D5D5D5;
        background-position: center;
        float: left;
    }

        .image-pattern-style:hover {
            border-color: gray;
            border-width: 2px;
        }

    .row {
        margin-left: 0px;
        margin-right: 0px;
        display: block;
    }

    .property-panel-header {
        padding-top: 15px;
        padding-bottom: 5px;
        font-weight: 600;
        font-size: 15px;
    }

    .row-header {
        font-size: 13px;
        font-weight: 600;
    }

    .row-header1 {
        font-size: 12px;
        padding-left: 2px;
        font-weight: 400;
    }

    .e-selected-orientation-style {
        border-color: #006CE6;
        border-width: 2px;
    }


    .e-selected-pattern-style {
        border-color: #006CE6;
        border-width: 2px;
    }

    .textboxstyle {
        padding-left: 0px;
        padding-right: 0px;
        float: left;
        width: 110px;
    }

    .e-checkbox-wrapper .e-label {
        font-size: 12px;
    }

    .col-xs-6 {
        padding-left: 0px;
        padding-right: 0px;
    }

    .sb-property-border {
        border-right: 1px solid #D7D7D7;
    }
</style>
@*End:Hidden*@
<div class="col-lg-8 control-section sb-property-border">
    <div id="diagram-space" class="content-wrapper">
        <SfDiagramComponent @ref="@Diagram" Height="690px" Tool="@DiagramTools.ZoomPan" NodeDefaults="@NodeDefaults" ConnectorDefaults="@ConnectorDefaults">
            <DataSourceSettings Id="Id" ParentId="Manager" DataSource="DataSource"></DataSourceSettings>
            <Layout @bind-Type="@type" @bind-HorizontalSpacing="@HorizontalSpacing" @bind-Orientation="@orientation" @bind-VerticalSpacing="@VerticalSpacing" @bind-HorizontalAlignment="@horizontalAlignment" @bind-VerticalAlignment="@verticalAlignment" GetLayoutInfo="GetLayoutInfo">
                <LayoutMargin @bind-Top="@top" @bind-Bottom="@bottom" @bind-Right="@right" @bind-Left="@left"></LayoutMargin>
            </Layout>
            <SnapSettings Constraints="SnapConstraints.None"></SnapSettings>
        </SfDiagramComponent>
    </div>
</div>
@*Hidden:Lines*@
<div class="col-lg-4 property-section">
    <div class="property-panel-header">
        Properties
    </div>
    <div class="row property-panel-content" id="appearance">
        <div class="row" style="padding-top: 10px;">
            <div class="row row-header">
                Orientation
            </div>
            <div id="orientation">
                <div class="row" style="padding-top: 8px">
                    <div title="Top to bottom Orientation" class="@dict["topToBottom"]" @onclick="ToptoBottomClick" id="topToBottom" style="background-image: url(images/diagram/common-orientation/top-to-bottom.png);
        margin-right: 3px">
                    </div>
                    <div title="Bottom to top Orientation" class="@dict["bottomToTop"]" id="bottomToTop" @onclick="BottomtoTopClick" style="background-image: url(images/diagram/common-orientation/bottom-to-top.png);
        margin: 0px 3px">
                    </div>
                    <div title="Left to right Orientation" class="@dict["leftToRight"]" id="leftToRight" @onclick="LefttoRightClick" style="background-image: url(images/diagram/common-orientation/left-to-right.png); margin-right:0px 3px">
                    </div>
                </div>
                <div class="row" style="padding-top: 8px">
                    <div title="Right to left Orientation" class="@dict["rightToLeft"]" id="rightToLeft" @onclick="RighttoLeftClick" style="background-image: url(images/diagram/common-orientation/right-to-left.png);
        margin: 0px 3px">
                    </div>
                </div>
            </div>
            <div class="row row-header" style="padding-top: 10px">
                Subtree Alignment
            </div>
            <div id="pattern">
                <div class="row" style="padding-top: 8px;">
                    <div title="Sub tree alignment  : Alternate" class="@pattendict["pattern1"]" @onclick="Pattern1Click" id="pattern1" style="background-image: url(images/diagram/organization-model/vertical-alternate.png);
        margin-right: 3px">
                    </div>
                    <div title="Sub tree alignment  : Left" class="@pattendict["pattern2"]" @onclick="Pattern2Click" id="pattern2" style="background-image: url(images/diagram/organization-model/vertical-left.png);
        margin: 0px 3px">
                    </div>
                    <div title="Sub tree alignment  : Left" class="@pattendict["pattern3"]" @onclick="Pattern3Click" id="pattern3" style="background-image: url(images/diagram/organization-model/positive-vertical-left.png);
        margin: 0px 3px">
                    </div>
                </div>
                <div class="row" style="padding-top: 8px">
                    <div title="Sub tree alignment  : Right" class="@pattendict["pattern4"]" id="pattern4" @onclick="Pattern4Click" style="background-image: url(images/diagram/organization-model/negative-vertical-right.png);
        margin: 0px 3px">
                    </div>
                    <div title="Sub tree alignment  : Right" class="@pattendict["pattern5"]" id="pattern5" @onclick="Pattern5Click" style="background-image: url(images/diagram/organization-model/vertical-right.png);
        margin-right: 3px">
                    </div>
                    <div title="Sub tree alignment  : Balanced" class="@pattendict["pattern6"]" id="pattern6" @onclick="Pattern6Click" style="background-image: url(images/diagram/organization-model/horizontal-balanced.png);
        margin: 0px 3px">
                    </div>
                </div>
                <div class="row" style="padding-top: 8px">
                    <div title="Sub tree alignment  : Center" class="@pattendict["pattern7"]" id="pattern7" @onclick="Pattern7Click" style="background-image: url(images/diagram/organization-model/horizontal-center.png);
        margin: 0px 3px">
                    </div>
                    <div title="Sub tree alignment  : Left" class="@pattendict["pattern8"]" id="pattern8" @onclick="Pattern8Click" style="background-image: url(images/diagram/organization-model/horizontal-left.png);
        margin: 0px 3px">
                    </div>
                    <div title="Sub tree alignment  : Right" class="@pattendict["pattern9"]" id="pattern9" @onclick="Pattern9Click" style="background-image: url(images/diagram/organization-model/horizontal-right.png);
        margin: 0px 3px">
                    </div>
                </div>
            </div>
        </div>
    </div>
    <div class="row property-panel-content" style="padding-top: 10px">
        <div class="row row-header">
            Layout Spacing
        </div>
        <div class="row" style="padding-top: 8px">
            <div style="display: table;height: 35px;" class="textboxstyle">
                <div style="display: table-cell; vertical-align: middle">Horizontal Spacing</div>
            </div>
            <div class="textboxstyle">
                <SfNumericTextBox TValue="int?" ID="hSpacing" Format="###.##" Width="100%" Min="20" Max="60" Step="2" Value="@HValue">
                    <NumericTextBoxEvents TValue="int?" ValueChange="@HSpacingChange"></NumericTextBoxEvents>
                </SfNumericTextBox>
            </div>
        </div>
        <div class="row" style="padding-top: 8px">
            <div style="display: table;height: 35px;" class="textboxstyle">
                <div style="display: table-cell; vertical-align: middle">Vertical Spacing</div>
            </div>
            <div class="textboxstyle">
                <SfNumericTextBox TValue="int?" ID="vSpacing" Format="###.##" Width="100%" Min="20" Max="60" Step="2" Value="@VValue">
                    <NumericTextBoxEvents TValue="int?" ValueChange="VSpacingChange"></NumericTextBoxEvents>
                </SfNumericTextBox>
            </div>
        </div>
    </div>
</div>
@*End:Hidden*@
@code
    {
    public int? HValue { get; set; } = 30;
    public int? VValue { get; set; } = 30;
    SubTreeOrientation subTreeOrientation = SubTreeOrientation.Vertical;
    SubTreeAlignments subTreeAlignment = SubTreeAlignments.Right;
    LayoutOrientation orientation = LayoutOrientation.TopToBottom;
    LayoutType type = LayoutType.OrganizationalChart;
    HorizontalAlignment horizontalAlignment = HorizontalAlignment.Auto;
    VerticalAlignment verticalAlignment = VerticalAlignment.Auto;
    int HorizontalSpacing = 30;
    int VerticalSpacing = 30;
    double top = 50;
    double bottom = 50;
    double right = 50;
    double left = 50;
    double offset = 20;
    static string selecteditem = "image-pattern-style  e-selected-orientation-style";
    static string unselecteditem = "image-pattern-style";
    static string selectedPattenitem = "image-pattern-style  e-selected-pattern-style";
    Dictionary<string, string> dict = new Dictionary<string, string>() {
        { "topToBottom", selecteditem },
        { "bottomToTop", unselecteditem },
        { "leftToRight", unselecteditem },
        { "rightToLeft", unselecteditem }
    };
    Dictionary<string, string> pattendict = new Dictionary<string, string>() {
       { "pattern1", unselecteditem },
       { "pattern2", unselecteditem },
       { "pattern3", unselecteditem },
       { "pattern4", unselecteditem },
       { "pattern5", selectedPattenitem },
       { "pattern6", unselecteditem },
       { "pattern7", unselecteditem },
       { "pattern8", unselecteditem },
       { "pattern9", unselecteditem },
    };

    SfDiagramComponent Diagram;
    // Defines default values for Node object
    private void NodeDefaults(IDiagramObject obj)
    {
        Node node = obj as Node;
        if (node.Data is System.Text.Json.JsonElement)
        {
            node.Data = System.Text.Json.JsonSerializer.Deserialize<OrganizationalDetails>(node.Data.ToString());
        }
        OrganizationalDetails organizationData = node.Data as OrganizationalDetails;
        node.Width = 120;
        node.Height = 50;
        node.Style.Fill = organizationData.Color;
        node.Annotations = new DiagramObjectCollection<ShapeAnnotation>()
    {
                new ShapeAnnotation()
                {
                    Content = organizationData.Role,
                    Offset = new Point(0.5, 0.5),
                    Style = new TextShapeStyle() { Color = "white" }
                }
            };
    }
    // Defines default values for Connector object
    private void ConnectorDefaults(IDiagramObject connector)
    {
        (connector as Connector).Type = Segments.Orthogonal;
        (connector as Connector).TargetDecorator.Shape = DecoratorShapes.None;
        (connector as Connector).SourceDecorator.Shape = DecoratorShapes.None;
    }

    public class OrganizationalDetails
    {
        public string Id { get; set; }
        public string Role { get; set; }
        public string Color { get; set; }
        public string Manager { get; set; }
        public string ChartType { get; set; }


    }
    //DataSource Items.
    public List<OrganizationalDetails> DataSource = new List<OrganizationalDetails>()
{
        new OrganizationalDetails(){Id= "parent", Role= "Board", Color = "#71AF17", Manager = "",ChartType = "" },
        new OrganizationalDetails() { Id = "1",Role=  "General manager", Color = "#71AF17", Manager =  "parent", ChartType ="right"},
        new OrganizationalDetails() { Id = "11", Role= "Assistant general manager",Color =  "#71AF17", Manager =  "1",ChartType = ""},
        new OrganizationalDetails() { Id = "2", Role= "Human resource manager", Color = "#1859B7", Manager =  "1",ChartType = "right"},
        new OrganizationalDetails() { Id = "3", Role= "Trainers", Color = "#2E95D8",  Manager = "2", ChartType =""},
        new OrganizationalDetails() { Id = "4", Role= "Recruiting team",Color =  "#2E95D8", Manager =  "2",ChartType = ""},
        new OrganizationalDetails() { Id = "5", Role= "Finance asst. manager", Color = "#2E95D8", Manager =  "2", ChartType =""},
        new OrganizationalDetails() { Id = "6", Role= "Design manager", Color = "#1859B7", Manager =  "1", ChartType ="right"},
        new OrganizationalDetails() { Id = "7",Role=  "Design supervisor",Color =  "#2E95D8",  Manager = "6", ChartType =""},
        new OrganizationalDetails() { Id = "8",Role=  "Development supervisor",Color =  "#2E95D8", Manager =  "6",ChartType = ""},
        new OrganizationalDetails() { Id = "9",Role=  "Drafting supervisor", Color = "#2E95D8",  Manager = "6",ChartType = ""},
        new OrganizationalDetails() { Id = "10",Role=  "Operations manager",Color =  "#1859B7", Manager =  "1", ChartType ="right"},
        new OrganizationalDetails() { Id = "11",Role=  "Statistics department",Color =  "#2E95D8",  Manager = "10",ChartType = ""},
        new OrganizationalDetails() { Id = "12",Role=  "Logistics department",Color =  "#2E95D8", Manager =  "10", ChartType =""},
        new OrganizationalDetails() { Id = "16", Role=  "Logistics department", Color = "#1859B7", Manager =  "1", ChartType ="right"},
        new OrganizationalDetails() { Id = "17",Role=  "Overseas sales manager",Color =  "#2E95D8", Manager =  "16", ChartType =""},
        new OrganizationalDetails() { Id = "18", Role= "Petroleum manager", Color = "#2E95D8",  Manager = "16", ChartType =""},
        new OrganizationalDetails() { Id = "20",Role=  "Service department manager",Color =  "#2E95D8",  Manager = "16",ChartType = ""},
        new OrganizationalDetails() { Id = "21", Role= "Quality control department", Color = "#2E95D8",  Manager = "16", ChartType =""},

    };
    private int rows = 0;
    private string pattern;
    private TreeInfo GetLayoutInfo(IDiagramObject obj, TreeInfo options)
    {
        if (rows == 0)
        {
            if (rows == 0 && options.Rows != null)
                options.Rows = null;
            Node node = obj as Node;
            if (pattern == "Pattern3Click" || pattern == "Pattern4Click")
            {
                options.Offset = -50;
            }
            if ((node.Data as OrganizationalDetails).Role == "General manager")
            {
                options.Assistants.Add(options.Children[0]);
                options.Children.RemoveAt(0);
            }
            if (!options.HasSubTree)
            {
                options.Orientation = subTreeOrientation;
                options.Type = subTreeAlignment;
            }
        }
        else
        {
            if (!options.HasSubTree)
            {
                options.Type = subTreeAlignment;
                options.Orientation = subTreeOrientation;
                options.Offset = offset;
            }
        }
        return options;
    }

    public void LeftToRight()
    {
        orientation = LayoutOrientation.LeftToRight;
    }

    public class ImageFields
    {
        public string Text { get; set; }
    }


    private void HSpacingChange(Syncfusion.Blazor.Inputs.ChangeEventArgs<int?> args)
    {
        HValue = (int)args.Value;
        HorizontalSpacing = int.Parse(args.Value.ToString());

    }
    private void VSpacingChange(Syncfusion.Blazor.Inputs.ChangeEventArgs<int?> args)
    {
        VValue = (int)args.Value;
        VerticalSpacing = int.Parse(args.Value.ToString());
    }

    private void ToptoBottomClick()
    {
        orientation = LayoutOrientation.TopToBottom;
        updateSelection("topToBottom");
    }
    private void LefttoRightClick()
    {
        orientation = LayoutOrientation.LeftToRight;
        updateSelection("leftToRight");
    }
    private void RighttoLeftClick()
    {
        orientation = LayoutOrientation.RightToLeft;
        updateSelection("rightToLeft");
    }
    private void BottomtoTopClick()
    {
        orientation = LayoutOrientation.BottomToTop;
        updateSelection("bottomToTop");
    }
    private async Task Pattern1Click()
    {
        pattern = "Pattern1Click";
        Diagram.BeginUpdate();
        subTreeAlignment = SubTreeAlignments.Alternate;
        subTreeOrientation = SubTreeOrientation.Vertical;
        offset = 20;
        updatePatternSelection("pattern1");
        _ = Diagram.EndUpdate();
        await Diagram.DoLayout();
    }
    private async Task Pattern2Click()
    {
        pattern = "Pattern2Click";
        Diagram.BeginUpdate();
        subTreeAlignment = SubTreeAlignments.Left;
        subTreeOrientation = SubTreeOrientation.Vertical;
        offset = 20;
        updatePatternSelection("pattern2");
        _ = Diagram.EndUpdate();
        await Diagram.DoLayout();
    }
    private async Task Pattern3Click()
    {
        pattern = "Pattern3Click";
        Diagram.BeginUpdate();
        subTreeAlignment = SubTreeAlignments.Left;
        subTreeOrientation = SubTreeOrientation.Vertical;
        offset = -50;
        updatePatternSelection("pattern3");
        _ = Diagram.EndUpdate();
        await Diagram.DoLayout();
    }
    private async Task Pattern4Click()
    {
        pattern = "Pattern4Click";
        Diagram.BeginUpdate();
        subTreeAlignment = SubTreeAlignments.Right;
        subTreeOrientation = SubTreeOrientation.Vertical;
        offset = -50;
        updatePatternSelection("pattern4");
        _ = Diagram.EndUpdate();
        await Diagram.DoLayout();
    }
    private async Task Pattern5Click()
    {
        pattern = "Pattern5Click";
        Diagram.BeginUpdate();
        subTreeAlignment = SubTreeAlignments.Right;
        subTreeOrientation = SubTreeOrientation.Vertical;
        offset = 20;
        updatePatternSelection("pattern5");
        _ = Diagram.EndUpdate();
        await Diagram.DoLayout();
    }
    private async Task Pattern6Click()
    {
        pattern = "Pattern6Click";
        Diagram.BeginUpdate();
        subTreeAlignment = SubTreeAlignments.Balanced;
        subTreeOrientation = SubTreeOrientation.Horizontal;
        offset = 20;
        updatePatternSelection("pattern6");
        _ = Diagram.EndUpdate();
        await Diagram.DoLayout();
    }
    private async Task Pattern7Click()
    {
        pattern = "Pattern7Click";
        Diagram.BeginUpdate();
        subTreeAlignment = SubTreeAlignments.Center;
        subTreeOrientation = SubTreeOrientation.Horizontal;
        offset = -50;
        updatePatternSelection("pattern7");
        _ = Diagram.EndUpdate();
        await Diagram.DoLayout();
    }
    private async Task Pattern8Click()
    {
        pattern = "Pattern8Click";
        Diagram.BeginUpdate();
        subTreeAlignment = SubTreeAlignments.Left;
        subTreeOrientation = SubTreeOrientation.Horizontal;
        offset = 20;
        updatePatternSelection("pattern8");
        _ = Diagram.EndUpdate();
        await Diagram.DoLayout();
    }
    private async Task Pattern9Click()
    {
        pattern = "Pattern9Click";
        Diagram.BeginUpdate();
        subTreeAlignment = SubTreeAlignments.Right;
        subTreeOrientation = SubTreeOrientation.Horizontal;
        offset = 20;
        updatePatternSelection("pattern9");
        await Diagram.EndUpdate();
        await Diagram.DoLayout();
    }
    private void updatePatternSelection(string id)
    {
        for (int i = 0; i < pattendict.Count; i++)
        {
            var value = pattendict.Values.ElementAt(i);
            var key = pattendict.Keys.ElementAt(i);
            if (pattendict.ContainsKey(id) && key == id)
            {
                value = selectedPattenitem;
            }
            else
            {
                value = unselecteditem;
            }
            pattendict.Remove(key);
            pattendict.Add(key, value);
        }
    }
    //Method is used to apply the selection to the prroperty panel.
    private void updateSelection(string id)
    {
        for (int i = 0; i < dict.Count; i++)
        {
            var value = dict.Values.ElementAt(i);
            var key = dict.Keys.ElementAt(i);
            if (dict.ContainsKey(id) && key == id)
            {
                value = selectedPattenitem;
            }
            else
            {
                value = unselecteditem;
            }
            dict.Remove(key);
            dict.Add(key, value);
        }
    }

}
